package myjava.o_byteCodeOperate;

import javassist.*;

import java.io.IOException;

/**
 * @Auther: cty
 * @Date: 2020/4/14 10:55
 * @Description: 使用javaassist生成一个新的类的字节码文件
 * 常见的字节码操作库：
 *      BCEL、ASM、CGLIB、Javassist
 * @version: 1.0
 */
public class Javassist {
    public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException {
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.makeClass("com.cty.User");

        // 创建属性
        CtField cf1 = CtField.make("private int uid;", cc);
        CtField cf2 = CtField.make("private String uname;", cc);
        CtField cf3 = CtField.make("private String pwd;", cc);
        cc.addField(cf1);
        cc.addField(cf2);
        cc.addField(cf3);

        // 创建方法
        CtMethod cm1 = CtMethod.make("public void setUid(int uid){this.uid=uid;}", cc);
        CtMethod cm2 = CtMethod.make("public int getUid(){return this.uid;}", cc);
        CtMethod cm3 = CtMethod.make("public void setUname(String uanme){this.uname=uname;}", cc);
        CtMethod cm4 = CtMethod.make("public void getUname(){return this.uname;}", cc);
        CtMethod cm5 = CtMethod.make("public void setPwd(String pwd){this.pwd=pwd;}", cc);
        CtMethod cm6 = CtMethod.make("public void getPwd(){return this.pwd;}", cc);
        cc.addMethod(cm1);
        cc.addMethod(cm2);
        cc.addMethod(cm3);
        cc.addMethod(cm4);
        cc.addMethod(cm5);
        cc.addMethod(cm6);

        // 创建构造器
        CtConstructor constructor1 = new CtConstructor(new CtClass[]{CtClass.intType, pool.get("java.lang.String"), pool.get("java.lang.String")}, cc);
        constructor1.setBody("{this.uid=uid; this.uname=uname; this.pwd=pwd;}");
        CtConstructor constructor2 = new CtConstructor(new CtClass[]{}, cc);
//        constructor2.setBody("{}");  // 默认body内也是空
        cc.addConstructor(constructor1);
        cc.addConstructor(constructor2);

        // 输出字节码文件
        String projectPath = System.getProperty("user.dir");
        String path = projectPath+"\\ByteCodeOperate\\myjava.p_classLoader.mycode\\";
        System.out.println("生成文件路径："+path);
        cc.writeFile(path);
        System.out.println("生成类字节码文件成功！");

    }
}
